import utils from '../utils'

export default class Collction {
    /**指定Model类型 */
    Model = null

    collection = []

    $config = {
        /**获取数据api */
        $retrieve: null,

        $update: null
    }

    constructor() {
        var options = arguments[0] || {};
        if (options.Model) {
            try {
                var instance = new options.Model();
                if (!this.isFunction(instance.assign))
                    throw new Error('传入的model不是集成自mode-base的model');
            } catch (err) {
                throw new Error('传入的model不是集成自mode-base的model');
            }

            this.Model = model;
        }
    }

    /**判断参数是不是函数 */
    isFunction(obj) {
        return Object.prototype.toString.call(obj) === '[object Function]';
    }

    /**判断参数是不是对象 */
    isObject(obj) {
        return Object.prototype.toString.call(obj) === '[object Object]';
    }

    /**判断参数是不是数组 */
    isArray(obj) {
        return Object.prototype.toString.call(obj) === '[object Array]';
    }

    /**把数据加到数组中 */
    add(model, options) {
        options = options || {};
        if (!(model instanceof this.Model))
            model = new this.Model().assign(model);

        if (!options.silence) {
            var vm = this;
            /**保存到数据库 参数可以传递*/
            return model.save(options).then((resolve, reject) => {
                /**保存到数据库成功后，加入到数组中*/
                vm.collection.push(model);
            })
        } else {
            this.collection.push(model);
        }
    }

    /**删除 */
    destroy(model, options) {

        if (!model || !model.length) throw new Error('model不能为null或者数组长度不能等于0')
        var idField = this.Model.$config.id;
        var isArray = this.isArray(model);
        var vm = this;

        if (isArray) {
            /**批量删除数据 */
            var models = model;
            var idCollection = [];
            models.forEach(item => {
                if (options.silence) {
                    var match = vm.findById(item[idField]);
                    this.collection.splice(match.index, 1)
                } else {
                    var match = vm.findById(item[idField]);
                    idCollection.push(match.model[idField]);
                }
            });

            if (!options.silence) {
                options.data = { data: idCollection }
                /**利用model实例来删除数据 */
                return models[0].destroy(options);
            }
        } else {
            /**单独删除数据 */

            var math = this.findById(model[idField]);
            if (math.index !== -1) {
                if (options.silence)
                    this.collection.splice(match.index, 1)
                else {
                    var vm = this;
                    match.destroy(options)
                        .then((resolve, reject) => {
                            vm.collection.splice(match.index, 1)
                        })
                        .catch(() => { })
                }

            }
        }
    }

    /**批量更新数据 */
    update(models, options) {
        if (!model || !model.length) throw new Error('model不能为null或者数组长度不能等于0')
        var idField = this.Model.$config.id;
        var vm = this;

        var models = model;
        var data = [];
        models.forEach(item => {
            if (options.silence) {
                var match = vm.findById(item[idField]);
                this.collection.splice(match.index, 1);
            } else {
                var match = vm.findById(item[idField]);
                data.push(match.model.convertPojo());
            }
        });

        if (!options.silence) {
            options.data = { data: idCollection }
            /**利用model实例来删除数据 */
            return new Propmise((resolve, reject) => {
                utils.$post({
                    urls: options.url || vm.$config.$update,
                    data: options.data || data,
                    success: function (res) {
                        /**如果使用时指定不要赋值，则返回会直接返回数据，让调用者自行处理返回的数据 */
                        if (!options.assignment) return resolve(arguments);
                        if (res && res.data && res.data.success === true) {

                            var result = res.data.result;
                            /**不是数组则不处理 */
                            if (!vm.isArray(result)) return resolve(arguments);
                            // TODO:更新当前数据
                            // result.forEach(item => {

                            //     var model = new vm.Model().assign(item);
                            //     vm.collection.push(model);
                            // });
                            resolve(arguments)
                        }
                        else
                            rejects(arguments)
                    },
                    fail: function () { reject(arguments) }
                })
            })
        }

    }

    /**从服务器获取数据 */
    retrieve() {
        var options = arguments[0] || {};
        /**是否需要复制，默认会复制 */
        options.assignment = options.assignment || true;
        if (!options.url && !this.$config.$retrieve)
            throw new Error('服务器地址未配置，请配置$confog.$retrieve或者传入{url:}')
        var vm = this;

        return new Promise((resolve, reject) => {
            utils.$get({
                url: options.url || vm.$config.$retrieve,
                data: options.data || {},
                success: function (res) {
                    /**如果使用时指定不要赋值，则返回会直接返回数据，让调用者自行处理返回的数据 */
                    if (!options.assignment) return resolve(arguments);
                    if (res && res.data && res.data.success === true) {
                        /**没有指定加在collection数组后面，所以清空 */
                        if (!options.append) vm.collection = [];
                        var result = res.data.result;
                        /**可能是分页 */
                        var items = result.items || result;
                        items.forEach(item => {
                            var model = new vm.Model().assign(item);
                            vm.collection.push(model);
                        });
                        resolve(arguments)
                    }
                    else
                        reject(arguments)
                },
                fail: function () { reject(arguments) }
            })
        })
    }

    /**返回数组对象 */
    toArray() { return this.collection }

    /**根据id找出数据 */
    findById(id) {
        var result = { model: null, index: -1 };
        this.collection.forEach((item, index) => {
            if (item[this.Model.$config.id].toString() === id.toString()) {
                result.model = item;
                result.index = index;
            }
        });

        return result;
    }
}